package com.info.zhiduoduo.common.constants;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.pagehelper.Page;
import com.info.zhiduoduo.common.exception.SmartException;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * Created by TerryJ on 2017-03-14.
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class SmartResult<T> {

	private int state = StatusMsg.StatusMsg_100.getState();//状态码
	private String msg = StatusMsg.StatusMsg_100.getMsg();//描述

	@JSONField(name = "object")
	private T Object;//返回对象信息
	private List<T> list;//返回数字信息
	private String systemerrormsg;//系统报错信息
	private int currpage = 0;    //当前页数
	private long totalrecords = 0;    //全记录数
	private int totalpages = 0;  //全页数

	@JSONField(serialize = false)
	@JsonIgnore
	public boolean isSuccessful() {
		return state == StatusMsg.StatusMsg_100.getState();
	}

	@JSONField(serialize = false)
	@JsonIgnore
	public boolean isFailed() {
		return !isSuccessful();
	}

	public static SmartResult success() {
		return new SmartResult();
	}

	public static <T> SmartResult<T> success(T t) {
		return new SmartResult<T>().setObject(t);
	}

	public static <T> SmartResult<T> success(List<T> list) {
		return new SmartResult<T>().setList(list);
	}

	public static SmartResult fail() {
		return fail(StatusMsg.StatusMsg_198);
	}

	public static SmartResult fail(String msg) {
		return fail(StatusMsg.StatusMsg_198.getState(), msg);
	}

	public static SmartResult fail(int state, String msg) {
		return success().setState(state).setMsg(msg);
	}

	public static SmartResult fail(StatusMsg statusMsg) {
		return success().setState(statusMsg.getState()).setMsg(statusMsg.getMsg());
	}

	public static SmartResult fail(StatusMsg statusMsg, String msg) {
		return success().setState(statusMsg.getState()).setMsg(msg);
	}

	public static <T> SmartResult fail(StatusMsg statusMsg, T t) {
		return success().setState(statusMsg.getState()).setMsg(statusMsg.getMsg()).setObject(t);
	}

	public static <T> SmartResult<T> of(List<T> list, long totalrecords, int currpage, int totalpages) {
		SmartResult<T> result = new SmartResult<>();
		result.list = list;
		result.currpage = currpage;
		result.totalrecords = totalrecords;
		result.totalpages = totalpages;
		return result;
	}

	public static <T> SmartResult<T> of(List<T> list, Page page) {
		return of(list, page.getTotal(), page.getPages(), page.getPageNum());
	}

	public static <T> SmartResult<T> ofPage(Page<T> page) {
		return SmartResult.of(page.getResult(), page.getTotal(), page.getPageNum(), page.getPages());
	}

	public static <T> SmartResult<T> of(T t, StatusMsg statusMsg) {
		SmartResult<T> result = success(t);
		result.setStateMsg(statusMsg);
		return result;
	}

	public static SmartResult ofException(SmartException e) {
		return fail(e.getState(), e.getMsg()).setObject(e.getData());
	}

	public void setStateMsg(StatusMsg statusMsg) {
		this.state = statusMsg.getState();
		this.msg = statusMsg.getMsg();
	}

	public static SmartResult ofErrorParam() {
		return fail(StatusMsg.StatusMsg_101);
	}

	public static SmartResult ofEmptyData() {
		return fail(StatusMsg.StatusMsg_102);
	}

	public static SmartResult ofOptFail() {
		return fail(StatusMsg.StatusMsg_199);
	}

	// create by build json plugin
	public JSONObject toJson() {
		JSONObject jo = new JSONObject();
		jo.put("status", state);
		jo.put("msg", msg);
		jo.put("object", Object);
		jo.put("systemerrormsg", systemerrormsg);
		jo.put("currpage", currpage);
		jo.put("totalrecords", totalrecords);
		jo.put("totalpages", totalpages);
		return jo;
	}

	@Override
	public String toString() {
		return toJson().toString();
	}
}
